home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-07-08 | 6.4 KB | 215 lines | [TEXT/MMCC] |
- /************************************************************************/
- /* Project...: Standard C++ Library */
- /* Name......: New.cp */
- /* Purpose...: standard C++ library */
- /* Copyright.: ©Copyright 1994 by metrowerks inc. All rights reserved. */
- /************************************************************************/
-
- #include <new.h>
- #include <Memory.h>
-
- #pragma a6frames on
-
- #define NEWMODE_NONE 0 // do not define operator new/delete
- #define NEWMODE_SIMPLE 1 // call NewPtr/DisposPtr
- #define NEWMODE_NORMAL 2 // regular new/delete
-
- #define NEWMODE NEWMODE_NORMAL // mode used to compile this file
-
- // These macros are allow DebugNew.cp to redefine operators
- // new and delete in debug mode while not adding any overhead
- // for the non-debug case.
-
- #ifndef OPERATOR_NEW
- #define OPERATOR_NEW operator new
- #endif
- #ifndef OPERATOR_DELETE
- #define OPERATOR_DELETE operator delete
- #endif
-
- extern void (*new_handler)();
-
- #if NEWMODE==NEWMODE_SIMPLE
-
- /************************************************************************/
- /* Purpose..: Allocate memory */
- /* Input....: size of memory to allocate */
- /* Return...: pointer to memory or 0L */
- /************************************************************************/
- void *OPERATOR_NEW(size_t size,void *p)
- {
- return p;
- }
-
- /************************************************************************/
- /* Purpose..: Allocate memory */
- /* Input....: size of memory to allocate */
- /* Return...: pointer to memory or 0L */
- /************************************************************************/
- void *OPERATOR_NEW(size_t size)
- {
- void *ptr;
-
- while((ptr=NewPtr(size))==NULL)
- {
- if(new_handler) new_handler(); else return(NULL);
- }
- return(ptr);
- }
-
- /************************************************************************/
- /* Purpose..: Dispose memory */
- /* Input....: pointer to memory or 0L (no action if 0L) */
- /* Return...: --- */
- /************************************************************************/
- void OPERATOR_DELETE(void *ptr)
- {
- if(ptr) DisposPtr((Ptr)ptr);
- }
-
- #elif NEWMODE==NEWMODE_NORMAL
-
- typedef struct FreeMemList {
- struct FreeMemList *next;
- long size;
- } FreeMemList;
-
- static FreeMemList memlist; // dummy header block (always empty)
- static size_t _newpoolsize = 0x00010000L; // number of bytes allocated for a new pool
- static size_t _newnonptrmax = 0x00001000L; // any object bigger than this will call NewPtr(...) directly
-
- /************************************************************************/
- /* Purpose..: Set size of future allocation pools */
- /* Input....: size of future allocation pools */
- /* Return...: --- */
- /************************************************************************/
- void _set_newpoolsize(size_t size)
- {
- _newpoolsize=size;
- }
-
- /************************************************************************/
- /* Purpose..: Set NewPtr(...) pointer threshold */
- /* Input....: size of new threshold */
- /* Return...: --- */
- /************************************************************************/
- void _set_newnonptrmax(size_t size)
- {
- _newnonptrmax=size;
- }
-
- /************************************************************************/
- /* Purpose..: Preallocate an allocation pool */
- /* Input....: size of pool to allocate */
- /* Return...: 1: no error; 0: fail */
- /************************************************************************/
- char _prealloc_newpool(size_t size)
- {
- FreeMemList *list;
-
- if((list=(FreeMemList *)NewPtr(size))==NULL) return 0;
- list->next=memlist.next; list->size=size; memlist.next=list;
- return 1;
- }
-
- /************************************************************************/
- /* Purpose..: Allocate memory */
- /* Input....: size of memory to allocate */
- /* Return...: pointer to memory or 0L */
- /************************************************************************/
- void *OPERATOR_NEW(size_t /* size */,void *p)
- {
- return p;
- }
-
- /************************************************************************/
- /* Purpose..: Allocate memory */
- /* Input....: size of memory to allocate */
- /* Return...: pointer to memory or 0L */
- /************************************************************************/
- void *OPERATOR_NEW(size_t size)
- {
- Ptr ptr;
-
- size=(size&0xFFFFFFFC)+8; // alloc *4 quantity plus 4 extra bytes for size
-
- if(size>=_newnonptrmax)
- { // try to get pointer from OS
- while(1)
- {
- if((ptr=NewPtr(size))!=NULL) { *(long *)ptr=-1L; return(ptr+4); }
- if(new_handler) new_handler(); else return(NULL);
- }
- }
-
- while(1)
- {
- FreeMemList *list,*prev;
-
- for(prev=&memlist,list=prev->next; list; prev=list,list=list->next) if(size<=list->size)
- {
- alloc: if(list->size>=size+sizeof(FreeMemList))
- { // split this free block
- list->size-=size; ptr=(Ptr)list+list->size;
- *(long *)ptr=size; return(ptr+4);
- }
- // remove this block from list
- prev->next=list->next; *(long *)list=list->size; return((Ptr)list+4);
- }
-
- // not enough free memory in memlist (try to allocate a new Ptr from OS
- if((list=(FreeMemList *)NewPtr(_newpoolsize))==NULL)
- {
- if(new_handler) new_handler(); else return(NULL);
-
- // try to allocate a system block
- if((ptr=NewPtr(size))!=NULL) { *(long *)ptr=-1L; return(ptr+4); }
- }
- else
- {
- list->next=memlist.next; list->size=_newpoolsize;
- memlist.next=list; prev=&memlist; goto alloc;
- }
- }
- }
-
- /************************************************************************/
- /* Purpose..: Dispose memory */
- /* Input....: pointer to memory or 0L (no action if 0L) */
- /* Return...: --- */
- /************************************************************************/
- void OPERATOR_DELETE(void *ptr)
- {
- if(ptr)
- {
- long size;
-
- ptr=(Ptr)ptr-4; size=*(long *)ptr;
- if(size!=-1L)
- {
- FreeMemList *list,*prev;
-
- for(prev=&memlist,list=prev->next; list; prev=list,list=list->next)
- {
- if((Ptr)ptr+size==(Ptr)list)
- { // merge block in front of this list item
- prev->next=list->next; size+=list->size; list=prev; continue;
- }
- if((Ptr)ptr==(Ptr)list+list->size)
- { // merge block at the end of this list item
- prev->next=list->next; ptr=list; size+=list->size; list=prev; continue;
- }
- }
-
- list=(FreeMemList *)ptr; list->next=memlist.next; list->size=size; memlist.next=list;
- }
- else DisposPtr((Ptr)ptr);
- }
- }
-
- #else
-
- // no operator new/delete defined
-
- #endif
-